"""
case type   : 资源池化
case name   : ss_log_max_file_size参数验证
Create At   : 2023.10
Owner       : wx1224102
description :
    1、查看参数，校验原始默认值，当前参数值，参数类型，取值类型及范围
    2、修改参数为超出范围值
    3、修改参数为其他合理值，重启数据库使参数生效
    4、恢复原始值，恢复集群状态
expect      :
    1、原始值为10240，单位为KB，当前参数值为10240，参数类型为sighup，取值类型为integer类型，取值范围为1024~4194304
    2、修改失败，合理报错
    3、修改成功，重启成功
    4、恢复原始值成功，集群状态正常
"""

import os
import unittest
from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger


class SharedStorage(unittest.TestCase):

    def setUp(self):
        self.log = Logger()
        self.log.info(f'-----{os.path.basename(__file__)} start-----')
        self.constant = Constant()
        self.com = Common()
        self.pri_sh = CommonSH('PrimaryDbUser')
        self.param = 'ss_log_max_file_size'
        self.src = self.com.show_param(self.param)

        self.log.info('------检查数据库状态是否正常------')
        status = self.pri_sh.exec_cm_ctl('query', '-Cv')
        self.assertIn("cluster_state   : Normal", status)

    def test_shared_storage(self):
        text = '-----step1:查看参数,校验默认值等;expect:启动默认值为10240,单位为KB,当前参数值为10240,' \
               '参数类型为sighup类型,取值类型为integer类型,最小值为10240，最大值为4194304-----'
        self.log.info(text)

        pri_config = f'''select name,setting,unit,context,boot_val,reset_val,
            vartype,min_val,max_val from pg_settings where name = '{self.param}';'''
        self.log.info(pri_config)
        pri_res = self.pri_sh.execut_db_sql(pri_config)
        self.log.info(pri_res)

        res1 = pri_res.splitlines()[0].split('|')
        res2 = pri_res.splitlines()[-2].split('|')
        result = dict(zip(res1, res2))
        self.log.info(result)

        value_list1 = []
        for key, values in result.items():
            value_list1.append(values.strip())
        self.log.info(value_list1)
        self.assertEqual(f'{self.param}', value_list1[0].strip(), '参数名校验失败')
        self.assertEqual('10240', value_list1[1], '当前值校验失败')
        self.assertEqual('kB', value_list1[2], '取值单位校验失败')
        self.assertEqual('sighup', value_list1[3].strip(), '参数类型校验失败')
        self.assertEqual('10240', value_list1[4], '启动值校验失败')
        self.assertEqual('10240', value_list1[5], '默认值校验失败')
        self.assertEqual('integer', value_list1[6].strip(), '取值类型校验失败')
        self.assertEqual('1024', value_list1[7].strip(), '最小值校验失败')
        self.assertEqual('4194304', value_list1[8].strip(), '最大值校验失败')

        text = '-----step2:修改参数为超出范围值; expect:修改失败,合理报错-----'
        self.log.info(text)

        sql = f"""alter system set {self.param} to 1023;"""
        set_param1 = self.pri_sh.execut_db_sql(sql)
        self.log.info(set_param1)
        self.assertIn(f'ERROR:  1023 is outside the valid range for '
                      f'parameter "{self.param}"', set_param1, '参数修改成功')

        text = f'-----step3:修改参数值为其他合理值,重启集群; expect:修改成功，重启成功-----'
        self.log.info(text)

        set_param2 = self.pri_sh.execute_gsguc('set',
                                               self.constant.GSGUC_SUCCESS_MSG,
                                               f"{self.param} = 1024")
        self.log.info(set_param2)
        self.assertTrue(set_param2, '参数设置失败')

        db_restart = self.pri_sh.exec_cm_ctl('stop && cm_ctl start', '-t 60')
        self.log.info(db_restart)
        self.assertIn(self.constant.cm_start_success_msg, db_restart,
                      '重启数据库成功')

    def tearDown(self):
        text = '-----step4:恢复环境为初始值，恢复集群状态; expect:恢复初始值成功，集群状态正常-----'
        self.log.info(text)

        self.log.info('-----恢复参数初始值-----')
        recov_param = self.pri_sh.execute_gsguc('set',
                                                self.constant.GSGUC_SUCCESS_MSG,
                                                f"{self.param} = '{self.src}'")
        self.log.info(recov_param)

        self.log.info('-----重启集群-----')
        restart = self.pri_sh.exec_cm_ctl('stop && cm_ctl start')
        self.log.info(restart)

        self.assertTrue(recov_param, '参数修改失败')
        self.assertIn(self.constant.cm_start_success_msg, restart,
                      '执行失败' + text)
        self.log.info(f'-----{os.path.basename(__file__)} end-----')
